﻿using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using LogikBug.Collections;
using LogikBug.ModularMvc.Registration;

namespace LogikBug.ModularMvc
{
	public abstract class Module : DisposableObject, IModule
	{
		#region Fields

		private Assembly _assembly;
		private ReadOnly<string> _resources;
		private bool _isEnabled = true;

		#endregion

		#region Constructors

		protected Module()
		{
			var typeName = GetType().FullName;

			if (!string.IsNullOrEmpty(typeName))
			{
				Key = typeName.Replace(".", "_");
			}
		}

		#endregion

		#region Properties

		public object Key { get; protected set; }

		public string Name { get; protected set; }

		public bool IsEnabled
		{
			get
			{
				return _isEnabled;
			}
			set
			{
				if (IsOptional)
				{
					_isEnabled = value;
				}
			}
		}

		public bool IsOptional { get; protected set; }

		public decimal OrderPrecedence { get; protected set; }

		public IModuleProvider Provider { get; protected set; }

		public IEnumerable<string> Resources
		{
			get
			{
				if (_isEnabled)
				{
					if (_resources.IsNull())
					{
						_resources = Assembly.GetManifestResourceNames();
					}

					return _resources;
				}

				return Enumerable.Empty<string>();
			}
		}

		public Assembly Assembly
		{
			get
			{
				if (_assembly.IsNull())
				{
					_assembly = GetType().Assembly;
				}

				return _assembly;
			}
		}

		protected virtual IRegistrationContext RegistrationContext { get; set; }

		#endregion

		#region Methods

		protected abstract void Initialize(IRegistrationContext context);

		protected internal override void DisposeResources()
		{
		}

		public void Initialize(IModuleProvider provider, IRegistrationContext context)
		{
			Provider = provider;
			RegistrationContext = context;
			Initialize(context);
		}

		//public virtual void RegisterServices(IObjectRegistry serviceRegistry)
		//{
		//    serviceRegistry.RegisterAssembly(Assembly);
		//}

		#endregion
	}
}
